package com.solome.vertx;

import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.DES;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

import java.nio.charset.StandardCharsets;
import java.util.Objects;

/**
 * 会话密钥类，用于生成和解析加密的会话ID。 Session key class for generating and parsing encrypted
 * session IDs.
 */
@Setter
@Getter
@ToString
public class SessionKey {

	// 会话创建时间戳（秒），默认为当前时间
	// Session creation timestamp (in seconds), default is current time
	private long timestamp = System.currentTimeMillis() / 1000;

	// 用户ID，可为空
	// User ID, nullable
	private Long uId;

	// 账户名，可为空
	// Account name, nullable
	private String acc;

	// 环境标识，默认0
	// Environment identifier, default 0
	private int env;

	// DES加密密钥，静态常量避免硬编码泄露
	// DES encryption key, static constant to avoid hardcoding exposure
	private static final String DEFAULT_KEY = "66bf0f97610522a17f355a39";

	// DES加密实例，使用UTF-8编码的默认密钥
	// DES encryption instance using UTF-8 encoded default key
	private final DES des = SecureUtil.des(DEFAULT_KEY.getBytes(StandardCharsets.UTF_8));

	// 分隔符常量，避免魔法字符串
	// Delimiter constant to avoid magic strings
	private static final String DELIMITER = "?";

	/**
	 * 默认构造函数。 Default constructor.
	 */
	public SessionKey() {
		// 无需额外初始化 / No additional initialization needed
	}

	/**
	 * 从加密的会话ID构造实例。 Constructs instance from an encrypted session ID.
	 * 
	 * @param sessionID 加密的会话ID / Encrypted session ID
	 */
	public SessionKey(String sessionID) {
		setSessionID(sessionID);
	}

	/**
	 * 设置并解析加密的会话ID。 Sets and parses an encrypted session ID.
	 * 
	 * @param sessionID 加密的会话ID / Encrypted session ID
	 */
	public void setSessionID(String sessionID) {
		// 检查输入是否为空或无效
		// Check if input is null or empty
		if (Objects.isNull(sessionID) || sessionID.trim().isEmpty()) {
			return;
		}

		try {
			// 解密会话ID
			// Decrypt session ID
			String decrypted = des.decryptStr(sessionID);
			String[] parts = decrypted.split("\\" + DELIMITER, -1); // -1保留空字段 / -1 to keep empty fields

			// 确保字段数量正确
			// Ensure correct number of fields
			if (parts.length != 4) {
				throw new IllegalArgumentException("Invalid session ID format");
			}

			// 解析字段
			// Parse fields
			this.timestamp = Long.parseLong(parts[0]);
			this.uId = parts[1].isEmpty() ? null : Long.parseLong(parts[1]);
			this.acc = parts[2].isEmpty() ? null : parts[2];
			this.env = Integer.parseInt(parts[3]);
		} catch (Exception e) {
			// 记录错误但不抛出，避免中断调用者
			// Log error but don't throw, avoid interrupting caller
			System.err.println("解析会话ID失败 / Failed to parse session ID: " + e.getMessage());
		}
	}

	/**
	 * 封装并加密会话数据为会话ID。 Wraps and encrypts session data into a session ID.
	 * 
	 * @return 加密后的会话ID / Encrypted session ID
	 */
	public String wrap() {
		// 构建明文会话字符串
		// Build plaintext session string
		StringBuilder session = new StringBuilder().append(timestamp).append(DELIMITER).append(uId != null ? uId : "")
				.append(DELIMITER).append(acc != null ? acc : "").append(DELIMITER).append(env);

		// 加密并返回十六进制字符串
		// Encrypt and return hex string
		return des.encryptHex(session.toString());
	}

	/**
	 * 测试主方法，用于验证功能。 Test main method for functionality verification.
	 * 
	 * @param args 命令行参数 / Command-line arguments
	 */
	public static void main(String[] args) {
		SessionKey key = new SessionKey();
		key.setUId(100L);
		key.setAcc("testUser");
		key.setEnv(1);

		String wrapped = key.wrap();
		System.out.println("加密会话ID / Encrypted Session ID: " + wrapped);

		SessionKey parsed = new SessionKey(wrapped);
		System.out.println("解析结果 / Parsed Result: " + parsed);
	}
}